package com.jy.api.service.impl;

import com.jy.api.dao.CouponDao;
import com.jy.api.dao.CouponInstanceDao;
import com.jy.api.dao.MemberDao;
import com.jy.api.domain.Coupon;
import com.jy.api.domain.CouponInstance;
import com.jy.api.domain.CouponStatus;
import com.jy.api.domain.Member;
import com.jy.api.enums.DistributeType;
import com.jy.api.exception.MyException;
import com.jy.api.payRes.CouponDto;
import com.jy.api.service.CouponInstanceService;
import com.jy.api.service.CouponService;
import com.jy.api.service.MemberService;
import com.jy.api.signUpReq.admin.CouponSignUpReq;
import com.jy.api.signUpReq.admin.DistributeCouponSignUpReq;
import com.jy.api.util.JodaUtils;
import com.jy.api.util.MyDateUtils;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by lihu on 2017/11/17.
 */
@Slf4j
@Service
public class CouponServiceImpl implements CouponService {

    @Autowired
    CouponDao couponDao;

    @Autowired
    CouponInstanceService couponInstanceService;

    @Autowired
    MemberService memberService;
    @Autowired
    private CouponInstanceDao couponInstanceDao;
    @Autowired
    private MemberDao memberDao;

    @Override
    @Transactional
    public void saveOrUpdate(CouponSignUpReq couponSignUpReq) {
        //如果优惠卷ID 存在则表示做修改
        Coupon coupon = couponDao.findOne(couponSignUpReq.getId());
        if (coupon == null) {
            coupon = new Coupon();
            BeanUtils.copyProperties(couponSignUpReq, coupon);
        }
        coupon.setProductId(couponSignUpReq.getProductId());
        coupon.setProductName(couponSignUpReq.getProductName());
        try {
            if (StringUtil.isNotBlank(couponSignUpReq.getEndDate()) && StringUtil.isNotBlank(couponSignUpReq.getId())) {
                String endDate = couponSignUpReq.getEndDate().concat(" 23:59:59");
                couponInstanceDao.updateUserCouponStatusByDate(MyDateUtils.getDateFormatDd(endDate, "yyyy-MM-dd HH:mm:ss"), coupon.getId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //copy couponSignUpReq的值

        // String endDate = couponSignUpReq.getEndDate().concat(" 23:59:59");
        //  coupon.setStartTime(MyDateUtils.getDateFormatDd(couponSignUpReq.getStartDate(), "yyyy-MM-dd"));
        //
        //

        if (couponSignUpReq.getExpireDay() > 0) {
            coupon.setExpireDays(couponSignUpReq.getExpireDay());
        } else {
            int days = (int) ((coupon.getEndTime().getTime() - coupon.getStartTime().getTime()) / (1000 * 3600 * 24));
            if (StringUtil.isNotBlank(couponSignUpReq.getEndDate())) {
                String endDate = couponSignUpReq.getEndDate().concat(" 23:59:59");
                coupon.setEndTime(MyDateUtils.getDateFormatDd(endDate, "yyyy-MM-dd HH:mm:ss"));
                coupon.setExpireDays(days);
            }
        }
        coupon.setStatus(CouponStatus.ING);
        couponDao.save(coupon);

    }


    @Override
    public Page<Coupon> getCoupon(String storeId, Pageable pageable) {
        List<CouponStatus> statuses = new ArrayList<>();
        statuses.add(CouponStatus.ING);
        statuses.add(CouponStatus.NO);
        return couponDao.findByStoreIdAndStatusIn(storeId, statuses, pageable);
    }

    @Override
    public CouponDto getCouponAll(String storeId, CouponStatus couponStatus, Pageable pageable) {
        List<CouponStatus> statuses = new ArrayList<>();
        statuses.add(CouponStatus.ING);
        statuses.add(CouponStatus.NO);
        List<Coupon> coupons = couponDao.findByStoreIdAndStatusIn(storeId, statuses);
        List<Coupon> saveCoupons = new ArrayList<>();
        for (Coupon coupon : coupons) {
            if (coupon.getExpireDay() == 0) {
                switch (coupon.getStatus()) {
                    case NO:
                        if (coupon.getStartTime().getTime() < new Date().getTime() && coupon.getEndTime().getTime() > new Date().getTime()) {
                            coupon.setStatus(CouponStatus.ING);
                            saveCoupons.add(coupon);
                        }
                        if (coupon.getEndTime().getTime() < new Date().getTime()) {
                            coupon.setStatus(CouponStatus.EXPIRED);
                            saveCoupons.add(coupon);
                        }
                        break;
                    case ING:
                        if (coupon.getEndTime().getTime() < new Date().getTime()) {
                            coupon.setStatus(CouponStatus.EXPIRED);
                            saveCoupons.add(coupon);
                        }
                        break;
                }
            }
        }
        couponDao.save(saveCoupons);
        CouponDto couponDtos = new CouponDto();
        List<CouponDto.Dto> dtos = new ArrayList<>();
        Page<Coupon> content = couponDao.findByStoreIdAndStatus(storeId, couponStatus, pageable);
        for (Coupon coupon : content.getContent()) {
            CouponDto.Dto dto = new CouponDto.Dto(coupon);
            long sendCount = couponInstanceDao.countSendByCouponId(coupon.getId());
            long userCount = couponInstanceDao.countUseByCouponId(coupon.getId());
            dto.setSendCount(sendCount);
            dto.setUseCount(userCount);
            dto.setProductId(coupon.getProductId());
            dtos.add(dto);
        }
        couponDtos.setDtos(dtos);
        couponDtos.setTotalElements(content.getTotalElements());
        couponDtos.setTotalPages(content.getTotalPages());
        return couponDtos;
    }

    @Override
    public Page<Coupon> getCouponAll(String storeId, Pageable pageable) {
        List<CouponStatus> statuses = new ArrayList<>();
        statuses.add(CouponStatus.ING);
        statuses.add(CouponStatus.NO);
        return couponDao.findByStoreIdAndStatusIn(storeId, statuses, pageable);
    }

    @Override
    @Transactional
    public void deleteCoupon(String id) {
        Coupon coupon = couponDao.findOne(id);
        if (coupon == null) {
            throw new MyException("修改失败！优惠卷信息不存在！");
        }
        coupon.setEnabled(false);
        couponDao.save(coupon);
    }

    @Override
    public Coupon getFondId(String id) {
        return couponDao.findOne(id);
    }

    @Async
    @Override
    public void distributeCoupon(DistributeCouponSignUpReq signUpReq, Coupon coupon,
                                 String creatorId, String creatorName) {
        List<String> memberIds = new ArrayList<>();
        if (DistributeType.SINGLE == signUpReq.getDistributeType()) {
            memberIds = signUpReq.getMemeberIds();
        } else if (DistributeType.ALL == signUpReq.getDistributeType()) {
            memberIds = memberService.getAllMemberId(signUpReq.getStoreId());
        } else if (DistributeType.SLEEP == signUpReq.getDistributeType()) {
            memberIds = memberService.getSleepMemberIds(signUpReq.getStoreId()).
                    stream().map(e -> e.toString()).collect(Collectors.toList());
        }
        for (String memberId : memberIds) {
            for (int i = 0; i < signUpReq.getQty(); i++) {
                try {
                    log.info("发放人{},发放张数{}", memberId, i);
                    couponInstanceService.addCouponInstance(coupon, memberId, creatorId, creatorName);
                } catch (Exception ex) {
                    log.error("distributeCoupon is error:{}", ex);
                }
            }
        }
    }
}
